Introduction to R Shiny

By: Mårten Erlandsson

What is R Shiny?

  • R package and web development framework
  • Generates HTML code from R
  • User can run R code using an interface instead of coding
  • No prior knowledge in web development is needed
  • Shiny can do whatever R can do (if you allow it to)

Why learn R Shiny?

  • Give your R functions a user interface (UI)
  • Collaboration with people who don’t know R
  • Presenting complex results from analyses
  • Create a dashboard that automatically updates the data
  • Speed up the trial and error approach
  • It’s not too hard to learn if you have some R knowledge
  • You can suddenly be a web developer

Code structure of shiny

  • UI (Front end)

  • Server (Back end)

  • Run the app

  • R files

    • Single file (app.R)

    • Multiple file (ui.R & server.R)

Code structure - UI

  • UI (Front end)

    • Define the layout of the app’s user interface.

    • Create components for user input and output.

library(shiny)

ui <- fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputID = "bins", 
                  label = "Number of bins:",
                  min = 1, max = 50, value = 30
      )
    ),
    mainPanel(
      plotOutput(outputID = "distPlot")
    )
  )
)

Code structure - Server

  • UI (Front end)

    • Define the layout of the app’s user interface

    • Create components for user input and output

  • Server (Back end)

    • Makes user input available to use in R scripts

    • Process data

    • Send outputs back to UI

library(shiny)

ui <- fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputID = "bins", 
                  label = "Number of bins:",
                  min = 1, max = 50, value = 30
      )
    ),
    mainPanel(
      plotOutput(outputID = "distPlot")
    )
  )
)

server <- function(input, output) {
  output$distPlot <- renderPlot({
    x <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    hist(x, breaks = bins, col = 'darkgray', border = 'white',
         xlab = 'Waiting time to next eruption (in mins)',
         main = 'Histogram of waiting times')
    })
}

Code structure - Run

  • UI (Front end)

    • Define the layout of the app’s user interface.

    • Create components for user input and output.

  • Server (Back end)

    • Makes user input available to use in R scripts

    • Process the data

    • Send outputs back to UI

  • Run the app

    • Render to HTML
library(shiny)

ui <- fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputID = "bins", 
                  label = "Number of bins:",
                  min = 1, max = 50, value = 30
      )
    ),
    mainPanel(
      plotOutput(outputID = "distPlot")
    )
  )
)

server <- function(input, output) {
  output$distPlot <- renderPlot({
    x <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    hist(x, breaks = bins, col = 'darkgray', border = 'white',
         xlab = 'Waiting time to next eruption (in mins)',
         main = 'Histogram of waiting times')
    })
}

shinyApp(ui = ui, server = server)

Example app

The logic of a shiny app

Input and output objects

  • All inputs and outputs gets a unique ID
library(shiny)

ui <- fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputID = "bins", 
                  label = "Number of bins:",
                  min = 1, max = 50, value = 30
      )
    ),
    mainPanel(
      plotOutput(outputID = "distPlot")
    )
  )
)

server <- function(input, output) {
  output$distPlot <- renderPlot({
    x <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    hist(x, breaks = bins, col = 'darkgray', border = 'white',
         xlab = 'Waiting time to next eruption (in mins)',
         main = 'Histogram of waiting times')
    })
}

shinyApp(ui = ui, server = server)

Example app

The logic of a shiny app

Input and output objects

  • All inputs and outputs gets a unique ID
  • All input and output values are stored in one input and one output object
  • The output is used together with a render function
library(shiny)

ui <- fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputID = "bins", 
                  label = "Number of bins:",
                  min = 1, max = 50, value = 30
      )
    ),
    mainPanel(
      plotOutput(outputID = "distPlot")
    )
  )
)

server <- function(input, output) {
  output$distPlot <- renderPlot({
    x <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    hist(x, breaks = bins, col = 'darkgray', border = 'white',
         xlab = 'Waiting time to next eruption (in mins)',
         main = 'Histogram of waiting times')
    })
}

shinyApp(ui = ui, server = server)

Example app

Reactivity

  • x <- a + b
  • When an input changes, all related outputs are automatically updated
  • Shiny creates a graph of dependencies between components
  • Reactive expressions

output$distPlot <- renderPlot({
  x <- faithful[, 2]
  bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
  hist(x, breaks = bins, col = 'darkgray', border = 'white',
       xlab = 'Waiting time to next eruption (in mins)',
       main = 'Histogram of waiting times')
  })

App layout in base shiny

Page functions

  • fluidPage()

    • fluidRow()
    • column()
  • fillPage()

 

  • fixedPage()

  • navbarPage()

    • navbarMenu()

Layout functions

  • sidebarLayout()
  • splitLayout()
  • verticalLayout()
  • flowLayout()

Advanced layouts

Layout packages:

  • bs4Dash
  • shinydashboard
  • shinyMobile
  • shiny.semantic

Custom theming

Shiny UI Editor

Input components

  • actionButton()

  • checkboxInput()

    • checkboxGroupInput()
  • dateInput()

    • dateRangeInput()
  • fileInput()

  • numericInput()

  • radioButtons()

  • selectInput()

  • sliderInput()

  • textInput()

Output components

Output Render
textOutput() renderText()
verbatimTextOutput() renderPrint()
tableOutput() renderTable()
plotOutput() renderPlot()
uiOutput() renderUI()
imageOutput() renderImage()

More widget packages

Widget packages:

Output interactivity

  • Leaflet
  • DT
  • Plotly
  • Highcharter
  • shinyjs

Share an app

Showcase

Official apps

https://shiny.posit.co/r/gallery/

Some of my apps

Length distribution

WioSymphony

Eco

Bycatch risk

[]

Resources

Shiny extensions

https://github.com/nanxstats/awesome-shiny-extensions

Course

https://shiny.posit.co/r/getstarted/shiny-basics/lesson1/index.html

Video

https://laderast.github.io/edu/2021-03-20-a-gradual-introduction-to-shiny/

Books

https://mastering-shiny.org/index.html

https://engineering-shiny.org/

https://unleash-shiny.rinterface.com/

https://book.javascript-for-r.com/